import axios from "axios";
import Cookies from 'js-cookie';
import Many from "@/utils/many";
import { useRouter } from "vue-router";
import qs from 'qs';
import { config } from "process";

const router = useRouter();

const noticeErr = (error: any, config: any) => {
    if (!config.hideErrorAlert) {
        Many.notice({
            type: 'error',
            message: `${getErrorMsg(error)}`,
        });
    }
};

const getErrorMsg = (error: any) => {
    let errMsg = ""
    if (Many.notNull(error.message)) {
        errMsg = error.message
    }

    if (Many.isNull(errMsg) && Many.notNull(error.msg)) {
        errMsg = error.msg;
    }

    if (Many.isNull(errMsg)) {
        errMsg = '网络异常，请联系管理员';
    }
    return errMsg
};

const decorateErr = (err: any) => {
    const { response = {} } = err;
    const { data = {} } = response;
    return {
        code: err.code,
        displayCode: response.status || err.displayCode,
        displayMsg: err.displayMsg,
        message:
            data.error || response.statusText || err.message || err.msg || err.result || '网络异常，请联系管理员',
    };
}

interface ApiResponse {
    code: string;
    data: any;
    message: string;
}

const ContentTypes = {
    FORM_URLENCODED: 'application/x-www-form-urlencoded',
    FORM_DATA: 'multipart/form-data',
    TEXT_PLAIN: 'text/plain',
};

const filterEmptyFields = (obj: any) => {
    return Object.entries(obj).reduce((acc, [key, value]) => {
        if (value !== null && value !== undefined && value !== '') {
            acc[key] = value;
        }
        return acc;
    }, {} as any);
};

const ajax = (config: any, resolveCallback?: any, rejectCallback?: any): Promise<any> => {
    if (config.loading || config.loading === undefined) {
        Many.loading();
    }

    const ajaxPromis = new Promise((resolve, reject) => {
        try {
            let errorHandel = rejectCallback || resolveCallback;
            console.log("登录参数： ", config.params)

            let method = config.method || "get";
            let token = Cookies.get("token");

            let contentType = config.contentType || ContentTypes.FORM_URLENCODED;
            if (contentType === ContentTypes.FORM_URLENCODED) {
                config.params = qs.stringify(filterEmptyFields(config.params));
            }

            axios({
                url: config.url,
                method: method,
                params: method === "get" ? config.params || {} : undefined,
                data: method === "post" ? config.params || {} : undefined,
                headers: {
                    "Content-Type": config.contentType || ContentTypes.FORM_URLENCODED,
                    ...(token ? { "Authorization": `Bearer ${token}` } : {})
                }
            }).then((res) => {
                let response: ApiResponse = res.data;
                let successHandel = resolveCallback;

                if (["0000"].includes(response.code)) {
                    resolve(response);
                    if (typeof successHandel === "function") {
                        successHandel(response);
                    }
                } else {
                    if (response.code === "9800") {
                        // 登录信息过期，请重新登录
                        Many.confirm({
                            title: '提示',
                            message: '登录信息过期，请重新登录',
                        }, () => {
                            // todo 跳转到登录界面
                            router.push("/");
                        });
                        return;
                    }
                    reject(response);
                    if (typeof errorHandel === "function") {
                        errorHandel(response);
                    }
                    noticeErr(response, config);
                }
            }).catch((error) => {
                console.error("error: ", error);
                if (typeof errorHandel === "function") {
                    errorHandel(error);
                }
                noticeErr(decorateErr(error), config);
                reject(error);
            }).finally(() => {
                lazyHideLoading();
            });
        } catch (e) {
            console.error("error: ", e);
            noticeErr(decorateErr(e), config)
            lazyHideLoading();
        }
    })

    return ajaxPromis;
};

const lazyHideLoading = () => {
    setTimeout(() => {
        Many.hideLoading();
    }, 500);
}

export { ajax }